//
//  ConvertUtil.swift
//  MZPrinter
//
//  Created by lin tendy on 15/11/4.
//  Copyright © 2015年 Mazing Inc. All rights reserved.
//

import Foundation

//
// 数据转换工具
//
class ConvertUtil {
    
    static let hexStr: String = "0123456789ABCDEF";
    static let binaryArray: [String] = [ "0000", "0001", "0010", "0011",
    "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011",
    "1100", "1101", "1110", "1111" ]
    
    // int -> hex
    class func intToHex(num: Int) -> String {
        let hex = String(format: "%2x", num)
        return hex.uppercaseString.stringByReplacingOccurrencesOfString(" ", withString: "")
    }
    
    // 实现 substring(string, Range)
    class func substring(str: String, r: Range<Int>) -> String {
        let startIndex = str.startIndex.advancedBy(r.startIndex)
        let endIndex = str.startIndex.advancedBy(r.endIndex)
        return str[Range(start: startIndex, end: endIndex)]
    }
    
    // 相当于 java 的 charAt
    class func charAtAsString(str: String, index: Int) -> String {
        let startIndex = str.startIndex.advancedBy(index)
        let endIndex = str.startIndex.advancedBy(index + 1)
        return str[Range(start: startIndex, end: endIndex)]
    }
    
    // 二进制转换成16进制
    // 比如 11110000 转成 16 进制是 F0
    class func myBinaryStrToHexString(binaryStr: String) -> String {
        var hex = ""
        let f4 = substring(binaryStr, r: Range<Int>(start: 0, end: 4))
        let b4 = substring(binaryStr, r: Range<Int>(start: 4, end: 8))
    
        for var i = 0; i < binaryArray.count; ++i {
            if f4.isEqual(binaryArray[i]) {
                hex = hex + substring(hexStr, r: Range<Int>(start: i, end: i+1))
            }
        }
        for var i = 0; i < binaryArray.count; ++i {
            if b4.isEqual(binaryArray[i]) {
                hex += substring(hexStr, r: Range<Int>(start: i, end: i+1))
            }
        }
    
        return hex;
    }
    
    /*
     * 16进制转换成 2 进制
     * @param hexString 字符串
     * @return 将十六进制转换为字节数组
     */
    class func HexStringToBinary(hexString: String) -> [UInt8] {
        // hexString的长度对2取整，作为bytes的长度
        let len = hexString.characters.count / 2;
        var bytes = [UInt8](count: len, repeatedValue: 0)
        var high: UInt8 // 字节高四位
        var low: UInt8  // 字节低四位
        let tmpHexStr = hexStr as NSString;
    
        for var i = 0; i < len; ++i {
            // 右移四位得到高位
            let index1 = tmpHexStr.rangeOfString(charAtAsString(hexString, index: 2 * i)).location
            let index2 = tmpHexStr.rangeOfString(charAtAsString(hexString, index: 2 * i + 1)).location
            high = UInt8( ((index1 << 4) ))
            low = UInt8( index2 )
            bytes[i] = UInt8 (high & 0xF0 | low & 0x0F);// 高地位做或运算
        }
        return bytes;
    }
    
    /**
    *
    * @param bytes 数据流
    * @return 将二进制转换为十六进制字符输出
    */
    class func binaryToHexString(bytes: [Int8]) -> String {
    
        var result = ""
        var hex = ""
        let tmpHexStr = hexStr as NSString
        for b in bytes {
            // 字节高4位
            var index = Int(b) & 0xF0
            hex = String(tmpHexStr.characterAtIndex(index >> 4));
            // 字节低4位
            index = Int(b) & 0x0F
            hex += String(tmpHexStr.characterAtIndex(index));
            result += hex + " ";
        }
        return result;
    }
    
    
    /**
    * Convert char to byte
    *
    * @param c char
    * @return byte
    */
    class func charToByte(c: UInt8) -> UInt8 {
        let tmp = "0123456789ABCDEF" as NSString
        let str = String(bytes: [c], encoding: NSUTF8StringEncoding)
        let index = tmp.rangeOfString(str!).location
        return UInt8( index );
    }
    
    /** Convert hexString to bytes(可用) */
    class func hexStringToBytes(str: String) -> [UInt8] {
        if str.isEmpty {
            return [];
        }
        let tmp: NSString = str as NSString;
        let hexString = String(tmp.uppercaseString)
        let length = tmp.length / 2;
        var hexChars: [UInt8] = [UInt8] (hexString.utf8)
        var d: [UInt8] = [UInt8] (count: length, repeatedValue: 0)
        for var i = 0; i < length; ++i {
            let pos = i * 2;
            d[i] = UInt8( (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])) );
        }
        return d;
    }
    
    /** 二进制List<String>转为HexString */
    class func binaryListToHexStringList(list: [String]) -> [String] {
        var hexList: [String] = [String]()
        for binaryStr in list {
            var sb = ""
            for var i = 0; i < binaryStr.characters.count; i += 8 {
                let str = substring(binaryStr, r: Range<Int>(start: i, end: i+8))
                // 转成16进制
                let hexString = myBinaryStrToHexString(str)
                sb = sb + hexString
            }
            hexList.append(sb);
        }
        return hexList;
    
    }
    
    /**
    * 指令list转换为byte[]指令
    */
    class func hexList2Byte(list: [String]) -> [UInt8] {
        var commandList: [[UInt8]] = [[UInt8]]()
    
    
        for hexStr in list {
            commandList.append(hexStringToBytes(hexStr));
        }
        return join(commandList);
    }
    
    /**
     * 所有数组join在一起
     *
     */
    class func join(srcArrays: [[UInt8]]) -> [UInt8] {
        var tmp: [UInt8] = [UInt8](count: 0, repeatedValue: 0)
        
        for srcArray in srcArrays {
            tmp += srcArray;
        }
        return tmp;
    }

    // return the length of the text, in order to compute line width for print
    // 中文算做 2 个 byte
    // 英文是 1 个
    class func getTextLength(txt: String) -> Int {
        var count = 0
        for char in txt.utf16 {
            if (char < 255) {
                count += 1
            }
            else {
                count += 2
            }
        }
        return count
    }
}